package com.ysucode.aspect;

import com.ysucode.annotation.MyLogger;
import com.ysucode.domain.Log;
import com.ysucode.entity.Result;
import com.ysucode.service.log.LogService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Objects;

/**
 * 日志管理的切面类
 */
@Component
@Aspect
//@EnableAspectJAutoProxy //boot已经为我们自动配置了
public class LogAspect {
    @Autowired
    private LogService logService;

    //切入点:自定义注解加在哪个方法上,哪个方法就是切入点
    @Around("@annotation(myLogger)")
    public Object Log(ProceedingJoinPoint pjp, MyLogger myLogger) throws Throwable {
        //获取类名
        String className = pjp.getTarget().getClass().getName();
        //获取方法名
        String methodName = pjp.getSignature().getName();
        //获取注解值
        String value = myLogger.value();
        //获取request对象
        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
        //获取ip
        String ip = request.getRemoteAddr();
        //记录开始时间
        long startTime = System.currentTimeMillis();
        //执行切入点方法，proceed是切入点方法执行后的返回结果，void时返回null
        Object proceed = pjp.proceed();
        //记录结束时间
        long endTime = System.currentTimeMillis();
        //方法耗时
        long time = endTime - startTime;
        //判断是否是用户登录操作
        String status = "", message = "";
        if (proceed == null) {
            //登录时proceed为null
            boolean flag = myLogger.flag();
            if (flag) {
                status = "成功";
                message = "登录成功";
            } else {
                status = "失败";
                message = "用户名或密码错误";
            }
        } else {
            //记录执行状态（是否执行成功）
            status = ((Result) proceed).getFlag() ? "成功" : "失败";
            //记录执行成功或失败的详细信息
            message = ((Result) proceed).getMessage();
        }
        //封装Log对象，持久化到本地
        Log log = new Log();
        log.setMethod(methodName);
        log.setDescription(value);
        log.setStatus(status);
        log.setMessage(message);
        log.setTime(time);
        log.setIp(ip);
        logService.addLog(log);

//        System.out.println(proceed);

        return proceed;
    }
}
